/*!
 * jQuery fieldata plugin: simple get key-value(i.e. fieldname: value) Object
 * version 1.0 (2012-5-23)
 * Requires jQuery v1.3.2 or later
 * Dual licensed under the GPL licenses:
 * http://www.gnu.org/licenses/gpl.html
 * Authors: SongXiang
 * Email:  oraplen@gmail.com
 */

/**
 * Just use getFieldData([prefix[, prefixMap]]) method.
 * It will return an JavaScript Object contains key-value(i.e. fieldname: value) items, value in which will be an Array if there are namesake field element exists.
 * --Example:
 * ----Use: $("form:first").getFieldData();
 * ----Result: {"name": "foo", "sex": "female", "favourite": ['sport', 'music', 'cybergames'], "toy": "teddy bear"}
 *
 * Also you can add one or both parameter(s) when you need prefix, the parameter prefix(a string) will be add prefix to each fieldname, and the prefixMap should be an Object that contains key-value(i.e. fieldname: prefix) items, it's useful if you want the field-name specific has different prefix, and fieldname prefix in prefixMap has high level if both parameter specified
 * --Example:
 * ----Use: $("form:first").getFieldData("stu.", {"favourite": "stuFav.", "toy": "stuToy."});
 * ----Result: {"stu.name": "stu.foo", "stu.sex": "female", "stuFav.favourite": ['sport', 'music', 'cybergames'], "stuToy.toy": "teddy bear"}
 * 
 * You can directly use the returned Object as jQuery ajax data, or use $.param($("form:first").getFieldData()) the method to get HTTP Query String.
 * Method removeBlank() is used to remove field which name is blank string.
 * Method addField(name, value, usePrefix) is used to add or update item, the default value of usePrefix is true.
 * Method style(style) is used to specified the style of the dataMap, it can change your field's value as total "string"(duplicate values split with ","), total "array"(default) or "both"(1 value to String, duplicate values to Array)
 */
jQuery.fn.extend({
	getFieldData: function(prefix, prefixMap){
		/**
		 * Define the object
		 */
		function FielData(){};
		
		// set default prefix
		prefix=(!prefix)? "": prefix;
		prefixMap=(!prefixMap)? {}: prefixMap;
		
		var dataMap=new FielData();
		// find the field elements under this element
		this.find(":input:enabled").not(":input:checkbox:enabled:not(:checked), :input:radio:enabled:not(:checked)").add(this.find("input[type='hidden']")).add(this.find("input:file:enabled"))
			.each(function(){
				// get field name, set as blank string when undefined
				var name=(!jQuery(this).attr("name"))? "": jQuery(this).attr("name");
				// add prefix to field name, if field prefix doesn't specified in prefixMap, add default prefix
				name=(!prefixMap[name])&&prefixMap[name]!=""? prefix+name: prefixMap[name]+name;
				// add field
				(!dataMap[name])? dataMap[name]=[jQuery(this).val()]: dataMap[name].push(jQuery(this).val());
			}
		);
		
		// delete field which name is blank
		delete dataMap[prefix];
		
		// make 1-element field to string
		jQuery.each(dataMap, function(i, v)
		{
			if (jQuery.isArray(dataMap[i])&&dataMap[i].length<=1)
			{dataMap[i]=dataMap[i].length==1? dataMap[i][0]: "";}
		});
		
		return dataMap;
	}
});
